function OS_Map(host,id)
{
	this.$super=OS_Resource;
	if (this.$super(host,id)===false) return;
	delete this.$super;
	
	this.rowCount=0;
	this.colCount=0;
	this.mapdata=[];
	
	this.load=function(handler)
	{
		this.rowCount=Number(this.resourceNode.getElementsByTagName("size")[0].getElementsByTagName("rowCount")[0].childNodes[0].nodeValue);
		this.colCount=Number(this.resourceNode.getElementsByTagName("size")[0].getElementsByTagName("colCount")[0].childNodes[0].nodeValue);
		var defaultTid=this.resourceNode.getElementsByTagName("defaultT")[0].childNodes[0].nodeValue;
		var defaultT=OS_Resource.resource.get(defaultTid);
		for (var i=0;i<this.rowCount;i++)
		{
			var row=[];
			for (var j=0;j<this.colCount;j++)
			{
				var square={};
				square.terrain=defaultT;
				square.occupied=false;
				row.push(square);
			}
			this.mapdata.push(row);
		}
		
		var rows=this.resourceNode.getElementsByTagName("row");
		for (var i=0;i<rows.length;i++)
		{
			var row=rows[i];
			var row_index=Number(row.getAttribute("index"));
			var cols=row.getElementsByTagName("col");
			for (var j=0;j<cols.length;j++)
			{
				var col=cols[j];
				var col_index=Number(col.getAttribute("index"));
				var square=this.mapdata[row_index][col_index];
				if (col.getElementsByTagName("t").length>0)
				{
					var terrainId=col.getElementsByTagName("t")[0].childNodes[0].nodeValue;
					square.terrain=OS_Resource.resource.get(terrainId);
				}
				if (col.getElementsByTagName("c").length>0)
				{
					var coveringId=col.getElementsByTagName("c")[0].childNodes[0].nodeValue;
					square.covering=OS_Resource.resource.get(coveringId);
				}
				if (col.getElementsByTagName("o").length>0)
				{
					var ornamentId=col.getElementsByTagName("o")[0].childNodes[0].nodeValue;
					square.ornament=OS_Resource.resource.get(ornamentId);
				}
			}
		}
		this.loaded=true;
		handler(this);
	}
	
	this.drawBelowCache=function()
	{
		this.belowCacheCanvas=document.createElement("canvas");
		this.belowCacheCanvas.width=this.colCount*host.config.squarewidth;
		this.belowCacheCanvas.height=this.rowCount*host.config.squareheight;
		this.belowCacheContext=this.belowCacheCanvas.getContext("2d");
		for (var i=0;i<this.rowCount;i++)
		{
			for (var j=0;j<this.colCount;j++)
			{
				var offsetx=j*host.config.squarewidth;
				var offsety=i*host.config.squareheight;
				if (!this.mapdata[i][j].terrain.integrate)
				{
					host.stage.draw(this.mapdata[i][j].terrain,offsetx,offsety,this.belowCacheContext);
				}
				else
				{
					host.stage.fix(this,"terrain",i,j,this.belowCacheContext);
				}
				if (!!this.mapdata[i][j].covering)
				{
					if (!this.mapdata[i][j].covering.integrate)
					{
						host.stage.draw(this.mapdata[i][j].covering,offsetx,offsety,this.belowCacheContext);
					}
					else
					{
						host.stage.fix(this,"covering",i,j,this.belowCacheContext);
					}
				}
				if (!!this.mapdata[i][j].ornament && !this.mapdata[i][j].ornament.cover)
				{
					host.stage.draw(this.mapdata[i][j].ornament,offsetx,offsety,this.belowCacheContext);
				}
			}
		}
	}
	
	this.drawBelowActor=function()
	{
		if (!this.belowCacheCanvas) this.drawBelowCache();
		host.stage.getContext().drawImage(this.belowCacheCanvas,0,0);
		for (var i=0;i<this.rowCount;i++)
		{
			for (var j=0;j<this.colCount;j++)
			{
				var offsetx=j*host.config.squarewidth;
				var offsety=i*host.config.squareheight;
				if (host.config.debug && this.mapdata[i][j].occupied)
				{
					host.stage.drawSquare("rgba(0,0,255,0.2)",offsetx,offsety);
				}
			}
		}
	}
	
	this.drawAboveCache=function()
	{
		this.aboveCacheCanvas=document.createElement("canvas");
		this.aboveCacheCanvas.width=this.colCount*host.config.squarewidth;
		this.aboveCacheCanvas.height=this.rowCount*host.config.squareheight;
		this.aboveCacheContext=this.aboveCacheCanvas.getContext("2d");
		for (var i=0;i<this.rowCount;i++)
		{
			for (var j=0;j<this.colCount;j++)
			{
				var offsetx=j*host.config.squarewidth;
				var offsety=i*host.config.squareheight;
				if (!!this.mapdata[i][j].ornament && this.mapdata[i][j].ornament.cover)
				{
					host.stage.draw(this.mapdata[i][j].ornament,offsetx,offsety);
				}
			}
		}
	}
	
	this.drawAboveActor=function()
	{
		for (var i=0;i<this.rowCount;i++)
		{
			for (var j=0;j<this.colCount;j++)
			{
				var offsetx=j*host.config.squarewidth;
				var offsety=i*host.config.squareheight;
				if (!!this.mapdata[i][j].ornament && this.mapdata[i][j].ornament.cover)
				{
					host.stage.draw(this.mapdata[i][j].ornament,offsetx,offsety);
				}
			}
		}
	}
	
	this.checkPass=function(row,col,coverable)
	{
		var square=this.mapdata[row][col];
		var pass=square.terrain.passable;
		if (!!square.covering)
		{
			pass=pass&&square.covering.passable;
		}
		if (!!square.ornament)
		{
			pass=pass&&square.ornament.passable;
		}
		if (!coverable)
		{
			pass=pass&&!square.occupied;
		}
		return pass;
	}
	
	//通行检测
	this.checkActivePosition=function(active)
	{
		var position_x=Math.round(active.currentPosition.x);
		var position_y=Math.round(active.currentPosition.y);
		if (position_x<0||position_x>(this.colCount-1)*host.config.squarewidth) return false;
		if (position_y<0||position_y>(this.rowCount-1)*host.config.squareheight) return false;
		var row1=Math.floor(position_y / host.config.squarewidth);
		var row2=Math.ceil(position_y / host.config.squarewidth);
		var col1=Math.floor(position_x / host.config.squareheight);
		var col2=Math.ceil(position_x / host.config.squareheight);
		if (!this.checkPass(row1,col1,active.coverable)) return false;
		if (!this.checkPass(row1,col2,active.coverable)) return false;
		if (!this.checkPass(row2,col1,active.coverable)) return false;
		if (!this.checkPass(row2,col2,active.coverable)) return false;
		return true;
	}
}

OS_Resource.Builder.put("map",OS_Map);